﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using DotSpatial.Projections;

namespace HaGisPack
{
    public class CoordinateConvert
    {

        /// <summary>
        /// 经纬度坐标转换成LCC坐标
        /// </summary>
        /// <param name="X">经度值</param>
        /// <param name="Y">纬度值</param>
        /// <param name="Lat1">标准纬线1</param>
        /// <param name="Lat2">标准纬线2</param>
        /// <param name="Lat0">原点纬度值</param>
        /// <param name="Lon0">原点经度值</param>
        /// <param name="FalseEasting">西偏移量</param>
        /// <param name="FalseNorthing">北偏移量</param>
        public static void LongLatToLCC(ref double X, ref  double Y, double Lat1, double Lat2, double Lat0, double Lon0, double FalseEasting, double FalseNorthing)
        {
            double[] XY = new double[2];
            XY[0] = X;
            XY[1] = Y;

            double[] Z = new double[1];
            Z[0] = 1;

            DotSpatial.Projections.ProjectionInfo projIn = KnownCoordinateSystems.Geographic.World.WGS1984;
            DotSpatial.Projections.ProjectionInfo projOut = new ProjectionInfo("+proj=lcc +lat_1=" + Lat1.ToString()
                + " +lat_2=" + Lat2.ToString() + " +lat_0=" + Lat0.ToString() + " +lon_0=" + Lon0.ToString()
                + " +x_0=" + FalseEasting.ToString() + " +y_0=" + FalseNorthing.ToString()
                + " +ellps=GRS80 +datum=NAD83 +units=m +no_defs ");

            DotSpatial.Projections.Reproject.ReprojectPoints(XY, Z, projIn, projOut, 0, 1);

            X = XY[0];
            Y = XY[1];

        }




        /// <summary>
        /// LCC转换成经纬度坐标
        /// </summary>
        /// <param name="X"></param>
        /// <param name="Y"></param>
        /// <param name="Lat1"></param>
        /// <param name="Lat2"></param>
        /// <param name="Lat0"></param>
        /// <param name="Lon0"></param>
        /// <param name="FalseEasting"></param>
        /// <param name="FalseNorthing"></param>
        public static void LCCToLongLat(ref double X, ref  double Y, double Lat1, double Lat2, double Lat0, double Lon0, double FalseEasting, double FalseNorthing)
        {
            double[] XY = new double[2];
            XY[0] = X;
            XY[1] = Y;

            double[] Z = new double[1];
            Z[0] = 1;

            DotSpatial.Projections.ProjectionInfo projIn = new ProjectionInfo("+proj=lcc +lat_1=" + Lat1.ToString()
                + " +lat_2=" + Lat2.ToString() + " +lat_0=" + Lat0.ToString() + " +lon_0=" + Lon0.ToString()
                + " +x_0=" + FalseEasting.ToString() + " +y_0=" + FalseNorthing.ToString()
                + " +ellps=GRS80 +datum=NAD83 +units=m +no_defs ");

            DotSpatial.Projections.ProjectionInfo projOut = KnownCoordinateSystems.Geographic.World.WGS1984;

            DotSpatial.Projections.Reproject.ReprojectPoints(XY, Z, projIn, projOut, 0, 1);

            X = XY[0];
            Y = XY[1];

        }


        /// <summary>
        /// UTM转经纬度
        /// </summary>
        /// <param name="X"></param>
        /// <param name="Y"></param>
        /// <param name="utmZone">utm区</param>
        /// <param name="NS">北半球为 true,南半球为 false </param>
        public static void UTMToLongLat(ref double X, ref  double Y, int utmZone,bool NS)
        {
            double[] XY = new double[2];
            XY[0] = X;
            XY[1] = Y;

            double[] Z = new double[1];
            Z[0] = 1;

            string utmStr="";
            if (NS == false)  //南半球
            {
                utmStr = "+proj=utm +zone=" + utmZone.ToString() + " +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ";
            }
            else
            {
                utmStr = "+proj=utm +zone=" + utmZone.ToString() + " +ellps=WGS84 +datum=WGS84 +units=m +no_defs ";
            }

            DotSpatial.Projections.ProjectionInfo projIn = new ProjectionInfo(utmStr);

            DotSpatial.Projections.ProjectionInfo projOut = KnownCoordinateSystems.Geographic.World.WGS1984;

            DotSpatial.Projections.Reproject.ReprojectPoints(XY, Z, projIn, projOut, 0, 1);

            X = XY[0];
            Y = XY[1];
        }


        /// <summary>
        /// 经纬度转UTM
        /// </summary>
        /// <param name="X"></param>
        /// <param name="Y"></param>
        public static void LongLatToUTM(ref double X, ref  double Y,ref int utmZone)
        {
            double[] XY = new double[2];
            XY[0] = X;
            XY[1] = Y;

            double[] Z = new double[1];
            Z[0] = 1;


            //int utmZone = 0;

            if (Y >= 0)  //北半球
            {
                if (X >= 0)
                {
                    utmZone = 31 + (int)Math.Truncate(X / 6);
                }
                else
                {
                    utmZone = 30 - (int)Math.Truncate(X / 6);
                }
            }
            else
            {
                if (X >= 0)
                {
                    utmZone = -31 + (int)Math.Truncate(X / 6);
                }
                else
                {
                    utmZone = -30 - (int)Math.Truncate(X / 6);
                }
 
            }

            string utmStr = "";

            if (Y<0)  //南半球
            {
                utmStr = "+proj=utm +zone=" + utmZone.ToString() + " +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ";
            }
            else
            {
                utmStr = "+proj=utm +zone=" + utmZone.ToString() + " +ellps=WGS84 +datum=WGS84 +units=m +no_defs ";
            }

            DotSpatial.Projections.ProjectionInfo projOut  = new ProjectionInfo(utmStr);

            DotSpatial.Projections.ProjectionInfo projIn = KnownCoordinateSystems.Geographic.World.WGS1984;

            DotSpatial.Projections.Reproject.ReprojectPoints(XY, Z, projIn, projOut, 0, 1);

            X = XY[0];
            Y = XY[1];



        }


    }
}
